package com.dyp.security.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
//prePostEnabled属性决定Spring Security在接口前注解是否可用@PreAuthorize,@PostAuthorize等注解,设置为true,会拦截加了这些注解的接口
//@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled=true)
@EnableWebSecurity
public class SecurityConfiguration {
    /**
     * 用户信息服务(配置用户账号、密码、角色)
     * @param passwordEncoder 密码加密器
     * @return 在内存用户详细信息管理器中
     */
    @Bean
    public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) {
        UserDetails user = User.withUsername("user")
                .password(passwordEncoder.encode("123456"))
                .roles("user")
                .build();

        UserDetails admin = User.withUsername("admin")
                .password(passwordEncoder.encode("123456"))
                .roles("user", "admin")
                .build();

        return new InMemoryUserDetailsManager(user, admin);
    }

    /**
     * 密码加密器  配置了InMemoryUserDetailsManager需要配置。
     * 如果不配置提示：Consider defining a bean of type 'org.springframework.security.crypto.password.PasswordEncoder' in your configuration.
     * @return 密码加密器的实例
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        return encoder;
    }
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .csrf(crsf->crsf.disable())
                .formLogin(Customizer.withDefaults())
                .authorizeHttpRequests((authorizeHttpRequests) ->
                        authorizeHttpRequests
                                .requestMatchers("/login").permitAll()
                                .requestMatchers("/static/**","/resources/**").permitAll()//资源目录
                                .requestMatchers("/user/**").permitAll()
                                .requestMatchers("/v3/**").authenticated()
                                .requestMatchers("/swagger-ui/**").authenticated()
//                                .requestMatchers("/swagger-ui/**").hasAnyRole("admin")
                );
        return http.build();
    }
}
